<template>
  <div class="train-model">
    <ContentWrap>
      <el-form :model="searchValue" ref="searchFormRef" label-suffix="：">
        <el-row>
          <el-col :span="7" class="pr-5">
            <el-form-item label="训练任务名称" prop="name">
              <ns-input v-model="searchValue.name" clearable placeholder="请输入训练任务名称" />
            </el-form-item>
          </el-col>
          <el-col :span="7" class="pr-5">
            <el-form-item label="任务状态" prop="status">
              <el-select v-model="searchValue.status" clearable placeholder="请选择任务状态">
                <el-option
                  v-for="item in statusSearchList"
                  :label="item.label"
                  :key="item.value"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24" class="text-right">
            <el-button
              @click="search"
              type="primary"
              plain
              v-hasPermi="['system:trainModel:search']"
              >搜索</el-button
            >
            <el-button @click="reset">重置</el-button>
          </el-col>
        </el-row>
      </el-form>
    </ContentWrap>
    <ContentWrap>
      <el-form-item>
        <el-button
          type="primary"
          @click="edit('create', {})"
          v-hasPermi="['system:trainModel:create']"
          >新增</el-button
        >
        <el-button
          type="danger"
          @click="batchDelRow"
          plain
          :disabled="ids.length == 0"
          v-hasPermi="['system:trainModel:batchDelete']"
          >删除</el-button
        >
      </el-form-item>
      <AsyncTable
        :fetchData="fetchData"
        ref="tableRef"
        v-bind="tableInfo"
        @selection-change="selectChange"
      />
    </ContentWrap>
    <Dialog
      v-model="dialogVisible"
      :title="titleType == 'create' ? '新增训练任务模板' : '编辑训练任务'"
      width="30%"
      close-on-click-modal
      destroy-on-close
    >
      <el-form
        label-suffix="："
        label-width="100px"
        :rules="rules"
        :model="saveValue"
        ref="formRef"
      >
        <el-form-item label="任务名称" prop="name">
          <ns-input placeholder="请输入任务名称" v-model="saveValue.name" clearable />
        </el-form-item>
        <el-form-item label="备注" prop="comment">
          <ns-input
            placeholder="请输入备注"
            type="textarea"
            v-model.trim="saveValue.comment"
            :rows="6"
            :maxlength="150"
            @input="saveValue.comment = saveValue.comment.replace(/\s+/g, '')"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="save">确定</el-button>
        </span>
      </template>
    </Dialog>
    <Dialog
      v-model="adoptDialog"
      title="模型采用"
      width="30%"
      close-on-click-modal
      destroy-on-close
    >
      <el-form
        label-suffix="："
        label-width="100px"
        :rules="adoptRefRules"
        :model="adoptValue"
        ref="adoptRef"
      >
        <el-form-item prop="moduleId" label="模型名称" placeholder="请输入模型名称">
          <el-select v-model="adoptValue.moduleId" placeholder="请选择模型名称" clearable>
            <el-option
              v-for="item in modelList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item prop="moduleVersion" label="模型版本" placeholder="请输入模型版本">
          <ns-input
            v-model="adoptValue.moduleVersion"
            placeholder="请输入模型版本"
            maxlength="50"
            clearable
          />
        </el-form-item>
        <el-form-item prop="describe" label="备注">
          <ns-input
            type="textarea"
            v-model.trim="adoptValue.describe"
            :rows="6"
            :maxlength="200"
            placeholder="请输入备注"
            @input="adoptValue.describe = adoptValue.describe.replace(/\s+/g, '')"
          />
        </el-form-item>
        <el-form-item prop="status" label="是否启用">
          <el-radio-group v-model="adoptValue.status">
            <el-radio :label="1">是</el-radio>
            <el-radio :label="0">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item class="w-full color-#909399">
          <el-icon class="v-middle" color="#909399" size="16"><InfoFilled /></el-icon>
          <span>若启用当前版本，将自动停用该模型的其他版本</span>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="adoptDialog = false">取消</el-button>
          <el-button type="primary" @click="create">确定</el-button>
        </span>
      </template>
    </Dialog>
  </div>
</template>

<script setup lang="tsx">
import AsyncTable from '@/components/AsyncTable'
import * as api from '@/api/system/trainModel'
import { adoptModelVersion, modelManageList } from '@/api/machineModel/modelManage'
import { InfoFilled } from '@element-plus/icons-vue'
import { Loading, RefreshRight } from '@element-plus/icons-vue'
import dayjs from 'dayjs'
import { cloneDeep } from 'lodash-es'
import { useRouter } from 'vue-router'
const titleType = ref('')
const dialogVisible = ref(false)
const adoptDialog = ref(false)
const tableRef = ref()
const formRef = ref()
const searchFormRef = ref()
const adoptRef = ref()
const { proxy } = getCurrentInstance()
const ids = ref([])
const router = useRouter()
const modelList = ref([])
const adoptValue = ref({
  moduleId: '',
  moduleVersion: '',
  describe: '',
  moduleTaskId: '',
  status: 1
})

//有进行中的任务则定时刷新
let preTableData = []
let timer: number | null = null
const runtime = () => {
  clearTimeout(timer)
  timer = setTimeout(async () => {
    const isRunning = preTableData.some((item: any) => item.status == 2)
    if (isRunning) {
      tableRef.value.currentPageReload()
    }
  }, 6000)
}
const statusSearchList = [
  { label: '待启动', value: 1 },
  { label: '进行中', value: 2 },
  { label: '失败', value: 4 },
  { label: '成功', value: 5 },
  { label: '停止', value: 6 }
]
const statusList = {
  1: '待启动',
  2: '进行中',
  4: '失败',
  5: '成功',
  6: '停止'
}
const statusColor = {
  1: '',
  2: '#409EFF',
  3: '#E6A23C',
  4: '#F56C6C',
  5: '#67C23A',
  6: '#E6A23C'
}
const searchValue = reactive({
  name: '',
  status: ''
})
const saveValue = ref({
  name: '',
  comment: ''
})
const tableInfo = {
  columns: [
    {
      type: 'selection'
    },
    {
      prop: 'name',
      label: '训练任务名称'
    },
    {
      prop: 'comment',
      label: '备注'
    },
    {
      label: '执行进度',
      render: ({ row }) => {
        return (
          <>
            <el-progress percentage={parseFloat(row.progress)}></el-progress>
          </>
        )
      }
    },
    {
      label: '训练次数',
      render: ({ row }) => {
        return (
          <>
            <span>{row.count}</span>
          </>
        )
      }
    },
    {
      width: '140px',
      label: '状态',
      render: ({ row }) => {
        return (
          <>
            <span style={{ color: statusColor[row.status] }}>{statusList[row.status]}</span>
            {row.status == 2 ? (
              <el-icon class="el-icon is-loading" style="vertical-align:-3px;margin-left: 5px;">
                <Loading />
              </el-icon>
            ) : (
              ''
            )}
          </>
        )
      }
    },
    {
      prop: 'startTime',
      label: '训练开始时间'
    },
    {
      width: '320px',
      label: '操作项',
      render: ({ row }) => {
        return (
          <>
            {row.status != 2 ? (
              <el-button
                link
                size="small"
                type="primary"
                v-hasPermi={[['system:trainModel:start']]}
                onclick={() => {
                  operation('start', row)
                }}
              >
                开始
              </el-button>
            ) : (
              <el-button
                link
                size="small"
                type="primary"
                v-hasPermi={[['system:trainModel:stop']]}
                onclick={() => {
                  operation('stop', row)
                }}
              >
                停止
              </el-button>
            )}
            <el-button
              type="primary"
              size="small"
              link
              onClick={() => {
                edit('edit', row)
              }}
              v-hasPermi={[['system:trainModel:edit']]}
            >
              编辑
            </el-button>
            <el-button
              link
              size="small"
              type="primary"
              disabled={row.status === 2}
              onClick={() => {
                trainContent(row)
              }}
              v-hasPermi={[['system:trainModel:content']]}
            >
              训练内容
            </el-button>
            {/* {row.status == 5 ? ( */}
            <el-button
              link
              size="small"
              type="primary"
              disabled={row.status != 5}
              onClick={() => {
                adopt(row)
              }}
              v-hasPermi={[['system:trainModel:adopt']]}
            >
              采用
            </el-button>
            {/* ) : ( */}
            {/* '' */}
            {/* )} */}
            <ns-button
              link
              size="small"
              type="danger"
              style="margin-left:6px"
              confirm
              onClick={() => {
                singleDel(row)
              }}
              v-hasPermi={[['system:trainModel:singleDelete']]}
            >
              删除
            </ns-button>
          </>
        )
      }
    }
  ],
  data: []
}
const fetchData = async ({ page, pageSize }) => {
  const { data, count } = await api.getTrainList({
    page: page,
    pageSize,
    ...searchValue
  })
  preTableData = data
  runtime()
  return { data, count }
}
const search = () => {
  tableRef.value.resetPage()
  tableRef.value.fetchData()
}
const reset = () => {
  searchFormRef.value.resetFields()
  search()
}
const selectChange = (val) => {
  ids.value = []
  val.map((item) => {
    ids.value.push(item.id)
  })
}
const rules = reactive({
  name: [{ required: true, message: '请输入训练任务名称', trigger: 'blur' }]
})
const adoptRefRules = reactive({
  moduleId: [{ required: true, message: '请选择模型名称', trigger: 'blur' }],
  moduleVersion: [{ required: true, message: '请输入模型版本', trigger: 'blur' }]
})
// 批量删除
const batchDelRow = () => {
  proxy.$modal
    .confirm(`确定要删除所选数据吗？`)
    .then(() => {
      api.delTrainModel({ idList: ids.value }).then(({ code }) => {
        code === 200 && ElMessage.success('删除成功')
        code === 200 && search()
        if (code === 200) ids.value = []
      })
    })
    .catch(() => {})
}

// 刷新进度
const refresh = (row) => {
  api.refreshModelProcess({ taskId: row.id }).then(({ code }) => {
    code === 200 && ElMessage.success('刷新成功')
    code === 200 && search()
  })
}

//训练任务开始/停止
const operation = (type, row) => {
  api.statusOperation({ taskId: row.id, operation: type }).then(({ code }) => {
    code === 200 && ElMessage.success('操作成功')
    code === 200 && search()
  })
}
const singleDel = (row) => {
  api.delTrainModel({ idList: [row.id] }).then(({ code }) => {
    code === 200 && ElMessage.success('删除成功')
    code === 200 && search()
    if (code === 200) ids.value = []
  })
}

//采用模型
const adopt = (row) => {
  adoptDialog.value = true
  resetForm()
  adoptValue.value.moduleVersion = dayjs().format('YYYY-MM-DD HH:mm:ss')
  adoptValue.value.moduleTaskId = row.id
}
const edit = (type, row) => {
  titleType.value = type
  dialogVisible.value = true
  if (type == 'edit') {
    saveValue.value = cloneDeep(row)
  } else {
    resetForm()
  }
}
const create = async () => {
  const v = await adoptRef.value.validate()
  if (v) {
    const { code } = await adoptModelVersion(adoptValue.value)
    code === 200 && ElMessage.success('采用成功')
    code === 200 && search()
    code === 200 && (adoptDialog.value = false)
  }
}
const save = async () => {
  const v = await formRef.value.validate()
  if (v) {
    titleType.value == 'create'
      ? api.addTrainModel(saveValue.value).then(({ code }) => {
          code === 200 && ElMessage.success('添加成功')
          code === 200 && search()
          code === 200 && (dialogVisible.value = false)
        })
      : api.editTrainModel({ ...saveValue.value }).then(({ code }) => {
          code === 200 && ElMessage.success('编辑成功')
          code === 200 && search()
          code === 200 && (dialogVisible.value = false)
        })
  }
}
const trainContent = (row) => {
  router.push({
    path: '/system/trainContent',
    query: { moduleTaskId: row.id }
  })
}
const resetForm = () => {
  saveValue.value = {
    name: '',
    comment: ''
  }
  adoptValue.value = {
    moduleId: '',
    moduleVersion: '',
    describe: '',
    moduleTaskId: '',
    status: 1
  }
}
onMounted(() => {
  modelManageList({ page: 1, pageSize: 10000 }).then(({ data }) => {
    modelList.value = data
  })
})
onDeactivated(() => {
  clearTimeout(timer)
})
</script>

<style lang="scss">
.train-model {
  .el-select {
    width: 100%;
  }
}
.refresh-icon:hover {
  cursor: pointer;
}
</style>
